package com.xinchuang.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.xinchuang.comment.R;
import com.xinchuang.common.KeyWordSystem;
import com.xinchuang.entity.User;
import com.xinchuang.entity.image.ImageCut;
import com.xinchuang.entity.image.ImageGrid;
import com.xinchuang.entity.image.ImageResult;
import com.xinchuang.mapper.UserMapper;
import com.xinchuang.service.RasterService;
import com.xinchuang.service.TiffUtilService;
import com.xinchuang.service.image.ImageCutService;
import com.xinchuang.service.image.ImageGridService;
import com.xinchuang.service.image.ImageResultService;
import com.xinchuang.util.FileElseUtil;
import com.xinchuang.util.RedisUtil;
import com.xinchuang.utils.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.text.SimpleDateFormat;

import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.bind.annotation.*;
import com.alibaba.fastjson.JSON;
import reactor.core.publisher.Flux;

@Slf4j
@Service
@RequiredArgsConstructor
public class RasterServiceImpl implements RasterService {

    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private final ImageResultService imageResultService;

    private final UserMapper userMapper;

    private final ImageGridService imageGridService;

    private final KeyWordSystem keyWordSystem;

    private final ImageCutService imageCutService;

    private final RedisUtil redisUtil;

    private final TiffUtilService tiffUtilService;

    @Override
    public String imgList(JSONObject jsonObject) {
        //jsonobject解析获取标识
        String tarId = jsonObject.getString("tarId");
        //jsonobject解析获取页码
        Integer pageNum = jsonObject.getInteger("pageNum");
        //jsonobject解析获取页容
        Integer pageSize = jsonObject.getInteger("pageSize");
        Page<ImageResult> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<ImageResult> wrapper = new LambdaQueryWrapper<>();
//        wrapper.eq(ImageResult::getImageType, "0");
        if (StringUtils.isNotBlank(tarId)) {
            wrapper.like(ImageResult::getImageName, tarId);
        }
        wrapper.orderByDesc(ImageResult::getCreateTime);
        Page<ImageResult> resultPage = imageResultService.page(page, wrapper);
        JSONObject json = new JSONObject();
        json.put("total", resultPage.getTotal());
        json.put("pageAll", resultPage.getPages());
        json.put("pageNum", resultPage.getCurrent());
        json.put("pageSize", resultPage.getSize());
        if (CollectionUtil.isNotEmpty(resultPage.getRecords())) {
            List<Map<String, Object>> list = Lists.newArrayList();
            for (ImageResult record : resultPage.getRecords()) {
                Map<String, Object> map = new HashMap<>();
                map.put("tarId", record.getId());
                map.put("imgName", StringUtils.isBlank(record.getImageName()) ? "默认影像" : record.getImageName());
                LocalDate localDate = record.getUpdateTime().toLocalDate();
                Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
                map.put("updateTime", DateUtils.getDay(date));
                User user = userMapper.selectById(record.getCreatePersion());
                if (ObjectUtil.isNotEmpty(user)) {
                    map.put("userName", user.getName());
                } else {
                    map.put("userName", "");
                }
                map.put("thuUrl", keyWordSystem.getSERVER_URL() + record.getResultThumb());
                map.put("cutId", record.getImageRelease());
                ImageCut imageCut = imageCutService.getById(record.getImageRelease());
                map.put("position", FileElseUtil.getObjectToList(imageCut.getPosition()));
                list.add(map);
            }
            json.put("imgList", list);
        } else {
            json.put("imgList", new ArrayList<>());
        }
        return JSON.toJSONString(R.data(json));
    }

    @Override
    public String img(JSONObject jsonObject) {
        //jsonobject解析获取标识
        String tarId = jsonObject.getString("tarId");
        ImageResult result = imageResultService.getById(tarId);
        JSONArray ployDataList = new JSONArray();
        if (ObjectUtil.isNotEmpty(result) && StringUtils.isNotBlank(result.getPosition())) {
            ployDataList = JSONArray.parseArray(FileUtil.readString(keyWordSystem.getFILE_URL() + result.getPosition(), StandardCharsets.UTF_8));
        }
//        List<ImageGrid> imageGrids = imageGridService.lambdaQuery().eq(ImageGrid::getRelId, tarId).list();
//        if (CollectionUtil.isNotEmpty(imageGrids)) {
//            JSONObject jsons;
//            for (ImageGrid imageGrid : imageGrids) {
//                jsons = new JSONObject();
//                jsons.put("id", imageGrid.getPId());
//                jsons.put("type", MyUtil.toWeb(imageGrid.getPType()));
//                jsons.put("json", JSONArray.parseArray(imageGrid.getPJson()));
//                jsons.put("radius", imageGrid.getPValue());
//                ployDataList.add(jsons);
//            }
//        }
        return JSON.toJSONString(R.data(ployDataList));
    }

    @Override
    public String autoRaster(JSONObject jsonObject) {
        JSONArray positions = jsonObject.getJSONArray("positions");
        if (CollectionUtil.isEmpty(positions)) {
            return JSON.toJSONString(R.fail("栅格标绘信息不能为空"));
        }
        String id = jsonObject.getString("id");
        String tarId = jsonObject.getString("tarId");
        String type = jsonObject.getString("type");
        String cutId = jsonObject.getString("cutId");
        type = MyUtil.fromWeb(type);
        if (null == type) {
            return JSON.toJSONString(R.fail("不支持该类型的栅格"));
        }
        //标记
        String numb;
        if (StringUtils.isNotBlank(jsonObject.getString("numb"))) {
            numb = jsonObject.getString("numb");
        } else {
            numb = MyUtil.fromWeb(type).substring(0, 2);
        }

        String toType = jsonObject.getString("toType");
        toType = MyUtil.fromWeb(toType);
        if (null == toType) {
            return JSON.toJSONString(R.fail("不支持该类型的栅格"));
        }
//        if ("round".equals(type) && "rectangle".equals(toType)) {
//            return JSON.toJSONString(R.fail("栅格失败,暂不支持圆形栅格矩形"));
//        } else if ("round".equals(type) && "skewrectangle".equals(toType)) {
//            return JSON.toJSONString(R.fail("栅格失败,暂不支持圆形栅格矩形"));
//        } else if ("skewrectangle".equals(type) && "round".equals(toType)) {
//            return JSON.toJSONString(R.fail("栅格失败,暂不支持斜矩形栅格圆形"));
//        }
//        if ("rectangle".equals(type)) {
//            positions = MyUtil.toRectangle(positions);
//        }
        JSONArray array = null;
        if ("round".equals(type) && "round".equals(toType)) {
            //圆半径
            Double radius = jsonObject.getDouble("radius");
            //切圆半径
            Double isRadius = jsonObject.getDouble("number");
            if (ObjectUtil.isNull(radius)) {
                return JSON.toJSONString(R.fail("请输入圆形的半径"));
            }
            if (ObjectUtil.isNull(isRadius)) {
                return JSON.toJSONString(R.fail("请输入需要切出圆形的半径"));
            }
            array = GridUtil.roundToRound(radius, isRadius, positions);
        } else if ("rectangle".equals(type) && "round".equals(toType)) {
            //切圆半径
            Double isRadius = jsonObject.getDouble("number");
            if (ObjectUtil.isNull(isRadius)) {
                return JSON.toJSONString(R.fail("请输入圆形的半径"));
            }
            array = GridUtil.rectangleToRound(isRadius, positions);
        } else if ("rectangle".equals(type) && "rectangle".equals(toType)) {
            Double width = jsonObject.getDouble("width");
            if (ObjectUtil.isNull(width)) {
                return JSON.toJSONString(R.fail("请输入宽度"));
            }
            array = GridUtil.rectangleToRectangle(width, positions);
        } else if ("GeoPolygon".equals(type) && "GeoPolygon".equals(toType)) {
            Double width = jsonObject.getDouble("width");
            if (ObjectUtil.isNull(width)) {
                return JSON.toJSONString(R.fail("请输入宽度"));
            }
            array = GridUtil.geoPolygonToGeoPolygon(width, positions);
        } else {
            return JSON.toJSONString(R.fail("栅格失败,暂不支持此类格式"));
        }
        if (CollectionUtil.isNotEmpty(array)) {
            for (int i = 0; i < array.size(); i++) {
                JSONObject object = array.getJSONObject(i);
                object.put("numb", numb + (i + 1));
            }
            return JSON.toJSONString(R.data(array, "栅格成功"));
        }
//        ImageCut cut = imageCutService.getById(cutId);
//        String fileUrl = keyWordSystem.getFILE_URL() + "/file/process/" + id;
//        FileUtil.mkdir(fileUrl);
//        Double value = null;
//        if (null != width) {
//            value = width;
//        }
//        if (null != RunExeUtil.getProcessPost(
//                id,
//                keyWordSystem.getPythonUrl(),
//                fileUrl,
//                keyWordSystem.getFILE_URL() + cut.getImageUrl(),
//                type,
//                value,
//                null,
//                positions)) {
//            JSONObject processFile = RunExeUtil.getProcessFile(fileUrl + "/" + "res.json");
//            if (null != processFile) {
//                List<ImageGrid> list = new ArrayList<>();
//                ImageGrid grid;
//                for (int i = 0; i < processFile.getJSONArray("positions").size(); i++) {
//                    JSONArray obj = processFile.getJSONArray("positions").getJSONArray(i);
//                    grid = new ImageGrid();
//                    grid.setRelId(tarId);
//                    grid.setPId(UUID.randomUUID().toString());
//                    grid.setPType(processFile.getString("type"));
//                    if ("round".equals(processFile.getString("type"))) {
//                        grid.setPValue(processFile.getString("radius"));
//                    }
//                    grid.setPJson(obj.toJSONString());
//                    list.add(grid);
//                }
//                imageGridService.saveBatch(list);
//                JSONArray ployDataList = new JSONArray();
//                JSONObject jsons;
//                for (int i = 0; i < list.size(); i++) {
//                    ImageGrid imageGrid = list.get(i);
//                    jsons = new JSONObject();
//                    jsons.put("id", imageGrid.getPId());
//                    jsons.put("numb", numb + "-" + (i + 1));
//                    jsons.put("type", MyUtil.toWeb(imageGrid.getPType()));
//                    jsons.put("json", JSONArray.parseArray(imageGrid.getPJson()));
//                    jsons.put("radius", imageGrid.getPValue());
//                    ployDataList.add(jsons);
//                }
//                return JSON.toJSONString(R.data(ployDataList, "栅格成功"));
//            }
//            return JSON.toJSONString(R.fail("栅格数据异常,请调整后重试"));
//        }
        return JSON.toJSONString(R.fail("栅格失败,请确认参数后重试"));
    }

    @Override
    public String editPlotList(JSONObject jsonObject) {
        //jsonobject解析获取标识
        String tarId = jsonObject.getString("id");
        if (redisUtil.hasKey("EDIT" + tarId)) {
            return JSON.toJSONString(R.fail("正在保存，请勿重复操作"));
        } else {
            redisUtil.set("EDIT" + tarId, "栅格保存", 60 * 30);
        }
        try {
            ImageResult result = imageResultService.getById(tarId);
            if (ObjectUtil.isNotEmpty(result)) {
                JSONArray ployDataList = jsonObject.getJSONArray("ployDataList");
                ImageResult newImage = null;
                if ("2".equals(result.getImageType())) {
                    newImage = result;
                    if (CollectionUtil.isEmpty(ployDataList)) {
                        newImage.setPosition("");
                        imageResultService.save(newImage);
                        JSONObject json = new JSONObject();
                        json.put("tarId", newImage.getId());
                        return JSON.toJSONString(R.data(json, "保存成功"));
                    }
                } else {
                    if (CollectionUtil.isEmpty(ployDataList)) {
                        return JSON.toJSONString(R.fail("请绘制图像后保存"));
                    }
                    newImage = new ImageResult();
                    BeanUtil.copyProperties(result, newImage);
                    newImage.setId(null);
                    newImage.setImageName("栅格影像" + DateUtil.format(new Date(), "yyyyMMdd_HHmmss"));
                    newImage.setImageType("2");
                    newImage.setCreateTime(null);
                    newImage.setUpdateTime(null);
                }
                ImageResult edit = tiffUtilService.saveEdit(newImage, ployDataList);
                if (null != edit) {
                    imageResultService.saveOrUpdate(newImage);
                    JSONObject json = new JSONObject();
                    json.put("tarId", newImage.getId());
                    log.info("栅格成果保存完成");
                    return JSON.toJSONString(R.data(json, "保存成功"));
                }
                return JSON.toJSONString(R.fail("保存成果异常，请确认参数后重试"));
            }
            return JSON.toJSONString(R.fail("无数据"));
        } finally {
            redisUtil.del("EDIT" + tarId);
        }
    }

}
